﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;

namespace VSLoadTestCustomReportName
{
    /// <summary>
    ///     Report Entry Form is basically the form which takes user inputs to modify the name and description
    ///     of a Load Test Run Result
    /// </summary>
    public partial class ReportEntryForm : Form
    {
        private const string NoReportSelected = "None Selected";
        private const string ChooseAReport = "Choose a report from this list";

        /// <summary>
        ///     Initializes a new instance of the <see cref="ReportEntryForm" /> class.
        /// </summary>
        /// <param name="trxFiles">The TRX files.</param>
        public ReportEntryForm(List<TrxFile> trxFiles)
        {
            InitializeComponent();
            TrxFiles = trxFiles;
            PopulateComboBox();
        }

        /// <summary>
        ///     Gets the TRX files.
        /// </summary>
        /// <value>
        ///     The TRX files.
        /// </value>
        public List<TrxFile> TrxFiles { get; internal set; }

        /// <summary>
        ///     Handles the Click event of the objOkButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        private void objOkButton_Click(object sender, EventArgs e)
        {
            string selectedReport = objNameReportNameCombo.Text;
            string newReportName = objNameReportName.Text;
            string description = objNameDescription.Text;

            if (string.IsNullOrWhiteSpace(selectedReport))
            {
                ShowMessage("Please select a valid Report Name", 0);
                return;
            }

            if (string.Compare(NoReportSelected, selectedReport) == 0)
            {
                ShowMessage("Please select a Test Result before attempting to modify", 0);
                return;
            }

            if (string.Compare(ChooseAReport, selectedReport) == 0)
            {
                ShowMessage("Please do choose a report...", 0);
                return;
            }

            if (string.IsNullOrWhiteSpace(newReportName))
            {
                ShowMessage("Please provide some valid characters as New Report Name", 0);
                return;
            }

            if (string.IsNullOrWhiteSpace(description))
            {
                ShowMessage("Please provide some valid cahracters for Report descripiton", 0);
                return;
            }

            string resultsPath = string.Empty;

            foreach (TrxFile file in TrxFiles)
            {
                string resultsFileName = Path.GetFileName(file.FilePath);

                if (String.Equals(resultsFileName, objNameReportNameCombo.Text, StringComparison.OrdinalIgnoreCase))
                {
                    resultsPath = file.FilePath;
                    break;
                }
            }

            if (!string.IsNullOrWhiteSpace(resultsPath))
            {
                // Modify the .trx xml file.                
                var xDoc = new XmlDocument();
                var namespaces = new XmlNamespaceManager(xDoc.NameTable);
                namespaces.AddNamespace("ns", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010");

                if (xDoc != null)
                {
                    xDoc.Load(resultsPath);

                    XmlNode TestRunNode = xDoc.SelectSingleNode("//ns:TestRun", namespaces);
                    TestRunNode.Attributes["name"].Value = newReportName;

                    XmlNode LoadTestNode = xDoc.SelectSingleNode("//ns:TestRun/ns:TestDefinitions/ns:LoadTest",
                        namespaces);
                    LoadTestNode.Attributes["Name"].Value = newReportName;
                    LoadTestNode.Attributes["Description"].Value = description;

                    xDoc.Save(resultsPath);
                }
            }

            Dispose(true);
        }

        /// <summary>
        ///     Handles the Click event of the objCancelButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        private void objCancelButton_Click(object sender, EventArgs e)
        {
            Dispose(true);
        }

        #region User-Defined Methods

        /// <summary>
        ///     Populates the combo box.
        /// </summary>
        private void PopulateComboBox()
        {
            if (TrxFiles == null)
            {
                objNameReportNameCombo.Items.Add(NoReportSelected);
                return;
            }

            if (TrxFiles.Count > 0)
            {
                objNameReportNameCombo.Items.Add(ChooseAReport);

                var trxTaskFiles = new FileInfo[TrxFiles.Count];
                int counter = 0;
                foreach (TrxFile trxFile in TrxFiles)
                {
                    trxTaskFiles[counter] = trxFile.TrxFileInfo;
                    counter++;
                }

                Array.Sort(trxTaskFiles, (f1, f2) => f2.LastWriteTime.CompareTo(f1.LastWriteTime));

                foreach (FileInfo fi in trxTaskFiles)
                {
                    objNameReportNameCombo.Items.Add(Path.GetFileName(fi.FullName));
                }

                objNameReportNameCombo.SelectedIndex = 1;
            }
        }

        /// <summary>
        ///     Shows the message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="messageType">Type of the message.</param>
        private void ShowMessage(string message, int messageType = 0)
        {
            switch (messageType)
            {
                case 0:
                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 1:
                    MessageBox.Show(message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    break;
                case 2:
                    MessageBox.Show(message, "Stop", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    break;
                case 3:
                    MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
                default:
                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
        }

        #endregion
    }
}